/***HttpMsg By GYLite 2022-12-26
 * Http通讯基类，提供接发http通讯功能
*/
class HttpMsg {

	public static useCache:boolean = false;
	private static _instance:HttpMsg;	
	public static getInstance():HttpMsg
	{
		if(HttpMsg._instance == null)
			HttpMsg._instance = new HttpMsg;
		return HttpMsg._instance;
	}
	private _http:GYLite.GYLoader;
	private _header:Array<any>;
	private _contentType:string;
	private _c:number = 0;
	

	
	public constructor() {
		let s = this;
		s._http = new GYLite.GYLoader(0,5);
		s._contentType = "application/json;charset=UTF-8";				
	}
	public get header():Array<any>
	{let s = this;		
		if(s._header)return s._header;
		if(MsgBase.haveMsgHandle())
		{
			s._header = [										
				];
		}
		else
		{
			s._header = [					
				];
		}			
		
		return s._header;
	}
	public setHeader(headerKey:string, value:string):void
	{
		let s = this;
		let i:number,len:number;
		let obj:any;
		len = s.header.length;
		for(i=0;i<len;++i)
		{
			obj = s.header[i];
			for(var key in obj)
			{
				if(key == headerKey)
				{
					obj[key] = value;
					return;
				}
			}
		}
		obj = {};
		obj[headerKey] = value;
		s.header.push(obj);
	}
	private codeDic = {"section/updateSectionStatus":1001,
						"section/updateLinkStatus":1002,
						"course/learnerSectionLocation":1003,
						"learnerLink/learnerLinkLocation":1004,
						"classroom/score":1005,
						}
	public getCodeByURL(URL)
	{
		let s  = this;
		let keyArr = URL.split("/v1/app/")
		if(keyArr && keyArr.length>1)
		{
			let keyArr2 = keyArr[1].split("?")
			return s.codeDic[keyArr2[0]];
		}
		return null
	}
	public setHeaderTime(time:number):void
	{
		let s = this;
		let len:number;
		len = s.header.length;
		while(--len>-1)
		{
			if("klzz_ol_home_time" == s.header[len].key)
			{
				s.header[len].value = time;
				break;
			}
		}		
	}
	/**上传blob文件到oss
	 * @param blob或者GYLite.GYByteArray 文件数据
	 * @param ext 文件后缀 .xxx
	 * @param signature 签名
	 * @param calBack 回调 成功返回ossKey，失败返回null
	 * @param thisObj this指向
	*/
	public uploadFileToOSS(blob:Blob|GYLite.GYByteArray, ext:string="", signature:any, callBack:Function, thisObj:any, url:string=null):void
	{let s = this;
		if(url == null)
			url = HTTPConf.OSS_VOUCHER;
		signature.ext = ext;
		HttpMsg.getInstance().sendMsg(url, signature, HTTPConf.M_GET, function(d:any):void{
			if(d && d.data)
			{
				let formData:any;
				let filename = d.data.path;
				let ossToken:any;
				ossToken = JSON.parse(d.data.ossToken);
				formData = {};				
				formData.key = filename;//存储在oss的文件路径							
				formData.policy = ossToken.policy; //policy
				formData.OSSAccessKeyId = ossToken.accessid; //accessKeyId
				formData.success_action_status = "200"; //成功后返回的操作码
				formData.signature = ossToken.signature; //签名
				formData.file = blob;						
				HttpMsg.getInstance().sendMsg(d.data.ossDomain, formData, HTTPConf.M_POST,s.uploadRev,s,HTTPConf.MULTIPART,{callBack:callBack,thisObj:thisObj,ossKey:d.data.ossDomain+filename,id:d.data.id},false,Log.IMPORTANT);					
			}
			else
			{
				//获取blob上传凭证失败
				s.uploadRev({error:"voucherError"},{callBack:callBack,thisObj:thisObj,ossKey:null});
			}
		}, s);
	}
	private uploadRev(ossData:any,param:any=null):void
	{let s = this;
		if(ossData)
		{
			if(ossData.error == "voucherError")
			{
				Log.writeLog("获取上传凭证失败！" + (param?param.ossKey:""),Log.WARN);
				if(param && param.callBack!=null)
				{
					param.callBack.call(param.thisObj,null,null);
				}
				return;
			}
			if(param && param.callBack!=null)
			{
				param.callBack.call(param.thisObj,param.ossKey,param.id);
			}
		}
		else
		{
			//工程上传失败
			Log.writeLog("上传失败！" + (param?param.ossKey:""),Log.WARN);
			if(param && param.callBack!=null)
			{
				param.callBack.call(param.thisObj,null);
			}
		}
	}

	/**发送http请求
	 * @param url 请求接口
	 * @param data 发送的数据
	 * @param callBack 返回的回调
	 * @param thisObj 回调指向
	 * @param contentType 参数格式
	 * @param param 参数，不能传大数据，只能传小json
     * @param randomParam 是否加随机数，默认false
     * @param log等级 参考Log常量，默认Log.VERBOSE     	 
	 * @param header 指定头数据，默认null，则使用HttpMsg默认的header
	*/
	public sendMsg(url:string, data:any, method:string = "POST", callBack:Function=null, thisObj:any=null,contentType:string=null,param:any = null,randomParam:boolean=false,logLevel:number=Log.VERBOSE, header:any[]=null):void
	{
		let s = this;
		let str:any;
		let newData:any;
        if(url == null)
        {
            Log.writeLog("不能出入空url的http请求!" + (data ==null || GYLite.CommonUtil.GYIs(data, String)?data:JSON.stringify(data)),Log.ERROR);
            return;
        }            				
		if(contentType == null)
			contentType = s._contentType;
		if(randomParam)
		{
			if(url.indexOf("?") > -1)
				url += "rrr=" + (++s._c);
			else
				url += "?rrr=" + (++s._c);
		}
		url = url.indexOf("http")==0?url:(HTTPConf.httpRoot + url);
		if(method.toLocaleUpperCase() == HTTPConf.M_GET && data)
		{
			str = HttpMsg.Json2Query(data);
			url += "?" + str;
		}
		else if(contentType == HTTPConf.MULTIPART)
		{	
			let formData:MsMultiPartFormData = HttpMsg.Json2MsMultiPartFormData(data);
			contentType = "multipart/form-data; boundary="+formData.boundary;
			str = formData.getFormData();
		}
		else if(GYLite.CommonUtil.GYIs(data, GYLite.URLVariables) || GYLite.CommonUtil.GYIs(data, FormData))
		{
			GYLite.CommonUtil.GYIs(data, FormData);
			str = data;
		}
		else
			str = JSON.stringify(data);		
		newData = str;            			
		s._http.httpSend(url, s.recvMsg, s, GYLite.GYLoader.TYPE_TEXT, method, header?header:s.header, newData, contentType, {func:callBack,thisObject:thisObj,param:param,logLevel:logLevel});
		if(logLevel!=0)
			Log.writeLog("NET_" + MultiLang.str14 + url + "\ndata:" + ((GYLite.CommonUtil.GYIs(str, String)?str:JSON.stringify(str))), logLevel);
	}
	public recvMsg(l:GYLite.LoadInfo):void
	{
		let d:any;
		let dt:number = Date.now() - l.startTime;
		if(dt > 2000)
		{
			let str:string = Log.readProgressLog(l.progressInfo);
			 if(l.param && l.param.logLevel > 0)
				Log.writeLog("NET_time_cause longTime:"+ dt + "ms-" + l.path + "\n详情：" + str,Log.WARN);
		}
		let clientParam:any;
		clientParam = l.param.param;
		if(l.content)
		{
			if((clientParam == null || clientParam.dataType == null || clientParam.dataType == GYLite.GYLoader.TYPE_JSON) && GYLite.CommonUtil.GYIs(l.content.res, String))
				d = l.content.res == ""?{}:JSON.parse(l.content.res);
			else
				d = l.content.res;			
		}        

		if(clientParam && clientParam.ossKey && clientParam.ossKey.indexOf(l.path) > -1 && (l.content == null || l.content.res == ""))
		{
			d = {code:200};
		}
		else if(l.param && l.param.logLevel > 0 && (d == null || d == "" ))//|| (d.code!=0 && d.code!=200) //根据业务使用判断
		{
			Log.writeLog("接口返回异常！" + l.path + "-" + (d&&d.code!=0?JSON.stringify(d):""), Log.WARN);
		}
		
		let s= this;		
        if(l.param && l.param.logLevel && l.param.logLevel!=null)
		{         
			Log.writeLog("NET_" + MultiLang.str15 + l.path + "\ndata:"+ (d?JSON.stringify(d):null) + "-" + l.msg, l.param.logLevel?l.param.logLevel:Log.VERBOSE);
		}		
		if(l.param && l.param.func!=null)
		{
			if((<Function>l.param.func).length == 2)
				l.param.func.call(l.param.thisObject, d,l.param.param);
			else	
				l.param.func.call(l.param.thisObject, d);
		}
			
	}
	public static Json2FormData(d:any):FormData
	{		
		let formData:FormData = new FormData;
		for(var key in d)
		{
			formData.append(key, d[key]);			
		}
		return formData;
	}
	public static Json2MsMultiPartFormData(d:any):MsMultiPartFormData
	{				
		let formData:MsMultiPartFormData = new MsMultiPartFormData;
		for(var key in d)
		{		
			formData.append(key, d[key]);			
		}
		formData.prepareFormData();
		return formData;
	}
	
	public static Json2URLVariables(d:any):GYLite.URLVariables
	{
		let str:string = "";
		for(var key in d)
		{
			str += key + "=" + d[key] + "&";
		}
		str = str.substr(0, str.length - 1);
		return new GYLite.URLVariables(str);
	}
	public static Json2Query(d:any):string
	{
		let str:string = "";
		for(var key in d)
		{
			str += key + "=" + d[key] + "&";
		}
		str = str.substr(0, str.length - 1);
		return str;
	}
	public static query2Json(str:string):any
	{
		let arr:Array<string> = str.split("&");
		let i:number,len:number;
		let arr2:Array<any>;
		let obj:any = {};
		len = arr.length;
		for(i=0;i<len;++i)
		{
			arr2 = arr[i].split("=");
			obj[arr2[0]] = arr2[1];
		}
		return obj;
	}
	/**base64转Blob*/
	public static dataURLtoBlob(base64:string):Blob {
        let arr:string[] = base64.split(',');
        let mime:string = arr[0].match(/:(.*?);/)[1];
        let bstr:string = atob(arr[1]);
        let n:number = bstr.length;
        let u8arr:Uint8Array = new Uint8Array(n);
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new Blob([u8arr], { type: mime });
    }
	/**base64转字节数组*/
	public static base64ToArrayBuffer(base64:string):ArrayBuffer
	{		
		let bstr:string;
		let n:number;		
		bstr = atob(base64);
		n = bstr.length;
		let u8arr:Uint8Array = new Uint8Array(n);
		while (n--) {
			u8arr[n] = bstr.charCodeAt(n);
		}
		return u8arr;
	}
	/**数据检验
	 * @param d 数据
	 * @return 返回是否报错
	*/
	public static errorCheck(d:any):boolean
	{let s = this;
		if(d && d.errorCode == "00") 
		{
			return false;
		}
		Log.writeLog("NET_" + (d?"error:"+ d.errorCode + "-" + d.errorMessage:"error:null"),Log.WARN);
		return true;
	}

	
}